package com.r2r.fetus;

import java.nio.ByteBuffer;

import org.ssssssss.magicapi.Const;
import org.tio.core.intf.Packet;

/**
*
* @author zcg
*/
public abstract class FetusPacket extends Packet {
	public static final Short V1HEADER_LENGHT = 26;//消息头的长度 22(固定包头)+2(包长度)+1(床位号)+1(包类型)
	public static final Short V2HEADER_LENGHT = 7;//消息头的长度 3(固定包头)+2(包长度)+1(床位号)+1(包类型)
	public static final boolean TRANS_JSON = false;//传输内容格式，true=对象JSON串，false=二进制流
	public static final byte[] v1Header1 = new byte[]{0x02, 0x00, 0x04, 0x01, 0x02, 0x00, 0x04, 0x05, 0x0c, 0x00, 0x04, 0x04, 0x11, 0x12, 0x13, 0x14, 0x15, 0x06, 0x07, 0x08, 0x09, 0x0a};
	public static final byte[] v1Header2 = new byte[]{0x04, 0x0e, 0x01, 0x00, 0x01, 0x00, 0x18, (byte) 0xfc, (byte) 0x86, 0x01, 0x54, 0x01, 0x02, 0x00, 0x18, (byte) 0xfc, 0x7c, 0x01, 0x68, 0x01, 0x02, 0x00};
	public static final byte[] v2Header=new byte[]{(byte) 0xfe,(byte) 0xfe,0x68 };

	private byte[] head1=new byte[]{0x55,0x55,0x55,0x55};		// 	将来扩展
	private byte doubleFlag;				//	双胎标记
	/**
	 * 消息类型，其值在org.tio.fetus.common.Type中定义
	 */
	private byte type;
	
	// 床位号
	private byte bedNo;
	// 规约版本号
	private String pcgVersion = "V1";

	private byte[] body;

	public FetusPacket() {
		super();
	}
	
	public abstract int getDataLength();
	public abstract String getProtocolVersion();
	public abstract int getHeaderLength();
	public abstract byte[] getHeader();
	
	/**
	 * @return the body
	 */
	public byte[] getBody() {
		return body;
	}

	/**
	 * @return the type
	 */
	public byte getType() {
		return type;
	}

	/**
	 * @return 床位号
	 */
	public byte getBedNo() {
		return bedNo;
	}
	
	@Override
	public String logstr() {
		return "" + type;
	}

	/**
	 * @param body the body to set
	 */
	public void setBody(byte[] body) {
		this.body = body;
	}

	/**
	 * @param type the type to set
	 */
	public void setType(byte type) {
		this.type = type;
	}

	/**
	 * @param 设置床位号
	 */
	public void setBedNo(byte bedNo) {
		this.bedNo = bedNo;
	}

	/**
	 * @return the pcgVersion
	 */
	public String getPcgVersion() {
		return pcgVersion;
	}
	
	private short fetusmode;					//	分辨率
	private short fetusvolume;				//	胎心音量
	private short marked;					//	胎动标记，0x01为标记
	private short ucreset ;					// 	宫缩复位标记
	private short[] fhr=new short[4] ;		//	胎心一值
    private short[] fhr2=new short[4]; 		//	胎心二值，由于监护仪端未作单双胎判断，故将此项固定发送，无双胎时，该位恒为0
	private short fhr_high ;             	//  胎心报警高
	private short fhr_low ;              	//  胎心报警低
	private short fhr_level ;             	//  胎心报警级别
	private short fhr2_high ;             	//  胎心2报警高
	private short fhr2_low ;              	//  胎心2报警低
	private short fhr2_level ;             	//  胎心2报警级别	
	private short[] uc=new short[4] ;		//	 宫缩压值
	private short uc_high ;              	//  宫缩压值高
	private short uc_low ;               	//  宫缩压值低
	private short uc_level ;              	//  宫缩压值报警级别
	private short fhr_avg;
	private short fhr2_avg;
	private short uc_avg;

	/**
	 * @param pcgVersion the pcgVersion to set
	 */
	public void setPcgVersion(String pcgVersion) {
		this.pcgVersion = pcgVersion;
	}
	
	/**
	 * 根据byte[] body 转换成属性值
	 */
	public boolean bytesToValues(byte[] bytes) {
		if(bytes.length<(4+20+12))
			return false;
		short maxUc = 100;
		ByteBuffer buffer = ByteBuffer.wrap(bytes);
		buffer.order(Const.byteOrder);
		buffer.get(head1, 0, 4);
		if("V1".equals(getPcgVersion())){
			if(bytes.length<(44))
				return false;
			fetusmode = buffer.get();
			fetusvolume = buffer.get();
			marked = buffer.get();
			ucreset = buffer.get();
			fhr[0] = buffer.getShort();
			fhr[1] = buffer.getShort();
			fhr[2] = buffer.getShort();
			fhr[3] = buffer.getShort();
			fhr2[0] = buffer.getShort();
			fhr2[1] = buffer.getShort();
			fhr2[2] = buffer.getShort();
			fhr2[3] = buffer.getShort();
			fhr_avg = (short)((fhr[0]+fhr[1]+fhr[2]+fhr[3])/4);
			
			fhr2_avg=(short)((fhr2[0]+fhr2[1]+fhr2[2]+fhr2[3]));
			doubleFlag=(byte)0x00;
			if(fhr2_avg>0){
				fhr2_avg=(short)(fhr2_avg/4);
				doubleFlag=(byte)0x01;
			}
			fhr_high = buffer.getShort();
			fhr_low = buffer.getShort();
			fhr_level = buffer.getShort();
			uc[0] = buffer.getShort();
			uc[1] = buffer.getShort();
			uc[2] = buffer.getShort();
			uc[3] = buffer.getShort();
			uc = checkValue(uc,maxUc);
			uc_avg = (short)((uc[0]+uc[1]+uc[2]+uc[3])/4);
			uc_high = buffer.getShort();
			uc_low = buffer.getShort();
			uc_level = buffer.getShort();
			
		}else{
			doubleFlag=head1[3]==(byte)0x56?(byte)0x01:0x00;
			fetusmode = buffer.get();
			fetusvolume = buffer.get();
			marked = buffer.get();
			ucreset = buffer.get();
			fhr[0] = buffer.getShort();
			fhr[1] = buffer.getShort();
			fhr[2] = buffer.getShort();
			fhr[3] = buffer.getShort();
			fhr_avg = (short)((fhr[0]+fhr[1]+fhr[2]+fhr[3])/4);
			fhr_high = buffer.getShort();
			fhr_low = buffer.getShort();
			fhr_level = buffer.getShort();
			uc[0] = buffer.getShort();
			uc[1] = buffer.getShort();
			uc[2] = buffer.getShort();
			uc[3] = buffer.getShort();
			uc = checkValue(uc,maxUc);
			uc_avg = (short)((uc[0]+uc[1]+uc[2]+uc[3])/4);
			uc_high = buffer.getShort();
			uc_low = buffer.getShort();
			uc_level = buffer.getShort();
			//双胎胎心 位置是否在末尾	
			if(doubleFlag==0x01){
				fhr2[0] = buffer.getShort();
				fhr2[1] = buffer.getShort();
				fhr2[2] = buffer.getShort();
				fhr2[3] = buffer.getShort();
				fhr2_avg = (short)((fhr2[0]+fhr2[1]+fhr2[2]+fhr2[3])/4);
				fhr2_high = buffer.getShort();
				fhr2_low = buffer.getShort();
				fhr2_level = buffer.getShort();
			}
		}
		return true;
	}
	// 修改收到的值
	private short[] checkValue(short[] values,short max) {
		short[]valuesT = new short[values.length];
		for(int i=0;i<values.length;i++) {
			valuesT[i] = values[i]>max?max:values[i];
		}
		return valuesT;
	}
	/**
	 * 根据属性值 转换成byte[] body
	 */	
	public byte[] valuesToBytes() {
		ByteBuffer buffer = null;
			buffer =ByteBuffer.allocate(44);
		buffer.order(Const.byteOrder);
		if(doubleFlag==0x01)
			head1[3]=0x56;
		
		buffer.put(head1);
		buffer.put((byte)fetusmode);
		buffer.put((byte)fetusvolume);
		buffer.put((byte)marked);
		buffer.put((byte)ucreset);
		buffer.putShort(fhr[0]);
		buffer.putShort(fhr[1]);
		buffer.putShort(fhr[2]);
		buffer.putShort(fhr[3]);
		
			buffer.putShort(fhr2[0]);
			buffer.putShort(fhr2[1]);
			buffer.putShort(fhr2[2]);
			buffer.putShort(fhr2[3]);
			
		
		buffer.putShort(fhr_high);
		buffer.putShort(fhr_low);
		buffer.putShort(fhr_level);
		buffer.putShort(uc[0]);
		buffer.putShort(uc[1]);
		buffer.putShort(uc[2]);
		buffer.putShort(uc[3]);
		buffer.putShort(uc_high);
		buffer.putShort(uc_low);
		buffer.putShort(uc_level);

		return buffer.array();
	}
}
